#include <rtthread.h>
#include "enc28j60.h"
#include "stm32f10x.h"

/*
hardware for Fire ISO-V2.
INT: PC6
RST: PC7
*/
#define RESET_PORT          GPIOC
#define RESET_PIN           GPIO_Pin_7
#define INT_PORT            GPIOC
#define INT_PIN             GPIO_Pin_6
#define ENC28J60_EXTI_Line  EXTI_Line6

/*
enc28j60_isr call in stm32f10x_it.c
*/

static void enc28j60_int_config(void)
{
    GPIO_InitTypeDef	GPIO_InitStruct;
    NVIC_InitTypeDef NVIC_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);

    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_IPU;
    GPIO_InitStruct.GPIO_Pin   = INT_PIN;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(INT_PORT, &GPIO_InitStruct);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource6);

    /* Configure ENC28J60 EXTI Line to generate an interrupt on falling edge */
    EXTI_InitStructure.EXTI_Line = ENC28J60_EXTI_Line;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /* Enable the ENC28J60 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* Clear the ENC28J60 EXTI line pending bit */
    EXTI_ClearITPendingBit(ENC28J60_EXTI_Line);
}

void rt_hw_enc28j60_init(void)
{
    /* reset */
    {
        GPIO_InitTypeDef	GPIO_InitStruct;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);

        GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_Out_PP;
        GPIO_InitStruct.GPIO_Pin   = RESET_PIN;
        GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;

        GPIO_Init(RESET_PORT, &GPIO_InitStruct);

        GPIO_ResetBits(RESET_PORT, RESET_PIN);
        rt_thread_delay(rt_tick_from_millisecond(20));
        /* release reset */
        GPIO_SetBits(RESET_PORT, RESET_PIN);
        rt_thread_delay(rt_tick_from_millisecond(50));
    }

    enc28j60_attach("spi20");

    /* enc28j60 interrupt configure. */
    enc28j60_int_config();
}
